/*eslint-disable*/
let lan = 'zh'
if (window.config) {
  lan = window.config.language || lan
}
const lanMap = {
  zh: {
    urlErr: '[404] 请求地址不存在',
    sysErr: '系统异常, 请联系系统管理员',
    otherErr: '其他错误',
    daoErr: 'dao对象错误',
    emptyErr: '网络连接异常'
  },
  en: {
    urlErr: '[404] not found',
    sysErr: '[500] Internal Server Error',
    otherErr: 'Error ..',
    daoErr: 'sys err by dao',
    emptyErr: 'Network lost connection'
  }
}
const msg = lanMap[lan]
import axios from 'axios'
import { getToken, removeToken } from '@/utils/auth' // 获取token
import router from './router'
const httpMap = {
  200(resolve, reject, reData, dao, params, config) {
    let { data } = reData
    let server
    if (data && data.code + '' === '200') {
      data.code = data.code === '200' ? 'ok' : 'err'
      if (dao.out) {
        data = dao.out(data, params)
      }
      if (data?.data?.pageable) {
        const row = data.data.content
        const navi = data.data.pageable
        data.data = {
          row,
          navi
        }
      }
      server = serverMap[data.code]
    } else if (data.code) {
      server = httpMap[data.code] || httpMap._
    } else if (data) {
      if (typeof data === 'string') {
        if (/无法找到该Mock API/.test(data)) {
          window.$$.msg.error(
            `接口[ ${dao.url || dao} ] mock 数据连接失败, 请检查Eolinker配置`
          )
        } else {
          window.$$.msg.error(data)
        }
      }
      reject(`返回数据格式错误 dao=${dao.url ? dao.url : dao}`)
      return
    }
    server(resolve, reject, data, dao, params, config)
  },
  404(resolve, reject, reData) {
    if (reData && reData.response && reData.response.data) {
      window.$$.msg.error(msg.urlErr)
    } else {
      window.$$.msg.error(msg.urlErr)
    }
    reject()
  },
  302() {
    window.$$.msg.error(`[302] ??`)
  },
  401(resolve, reject, reData, dao) {
    reject(reData)
    removeToken()
    localStorage.removeItem('user')
    localStorage.removeItem('power')
    router.replace(`/login`)
  },
  500(resolve, reject, reData) {
    if (reData.message) {
      window.$$.msg.error(reData.message)
    } else {
      window.$$.msg.error(msg.sysErr)
    }
    reject(msg.sysErr)
  },
  _(resolve, reject, reData, url) {
    if (reData && reData.response) {
      window.$$.msg.error(
        `[${reData.response.status}] ${reData.response.statusText}`
      )
    } else {
      window.$$.msg.error(msg.otherErr)
      $c.error(url)
    }
    reject(reData)
  }
}
const serverMap = {
  err(resolve, reject, reData, dao, params, config) {
    if (!config.silent) {
      window.$$.msg.error(`${reData.message || reData.msg}`)
    }
    reject(reData)
  },
  ok(resolve, reject, reData, dao, params, config) {
    let re
    if (config.showMsg) {
      window.$$.msg.show(reData.message || reData.msg)
    }
    if (typeof reData.dataValue !== 'undefined') {
      re = reData.dataValue
    } else if (typeof reData.data !== 'undefined') {
      re = reData.data
    } else {
      re = {}
    }
    resolve(re)
  },
  302(resolve, reject, reData, dao, params, config) {
    // 错误
    if (!config.silent) {
      window.$$.msg.error(`${reData.message}`)
    }
    reject(reData)
  },
  _(resolve, reject, reData) {
    window.$$.msg.error(`未知错误: ${reData.message}`)
    reject(reData)
  }
}
const http = (method, dao, params, config = {}, jsonParams) => {
  let url
  // 处理应用中的固定入参数
  if (window.$app && window.$app.fixParams) {
    const p = $app.fixParams()
    params = Object.assign(params || {}, p)
  }
  if (typeof dao === 'string') {
    url = dao
  } else if (typeof dao === 'object') {
    url = dao.url
    if (!url) {
      window.$$.msg.error(msg.daoErr, dao)
      return
    }
  } else if (typeof dao === 'undefined') {
    window.$$.msg.error('dao 对象不存在,请仔细确认')
    $c.error(params)
    return
  }
  const api =
    config.apiPath || (window.config && window.config.apiPath) || '/api'
  const httpConfig = {
    method: method,
    url: api + '/' + url
  }
  if (params) {
    if (dao.in) {
      params = dao.in(params)
    }
    for (const key in params) {
      if (params[key] === null) {
        delete params[key]
      }
    }
  }
  // 判断用户是否已经登录
  const hasToken = getToken()
  httpConfig.headers = {
    // 'Content-Type': '2222'
    'x-token': hasToken
  }
  if (method === 'POST' && !config.isFormData) {
    httpConfig.data = params
    if (!jsonParams) {
      httpConfig.headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'x-token': hasToken
      }
      httpConfig.transformRequest = [
        data => {
          let ret = ''
          for (const it in data) {
            if (typeof data[it] === 'object' && data[it].length) {
              for (const r of data[it]) {
                ret +=
                  encodeURIComponent(it) + '=' + encodeURIComponent(r) + '&'
              }
            } else {
              ret +=
                encodeURIComponent(it) +
                '=' +
                encodeURIComponent(data[it]) +
                '&'
            }
          }
          return ret
        }
      ]
    }
  } else if (method === 'GET') {
    httpConfig.params = params
  } else {
    httpConfig.data = params
  }
  // 个别应用中是否展示全局loading
  const appLoading = lev => {
    if (config && window.$app && !config.noLoad && window.$app.setLoad) {
      $app.setLoad(lev)
    }
  }
  return new Promise((resolve, reject) => {
    appLoading(1)
    // $c.log(9999,httpConfig)
    axios(httpConfig)
      .then(r => {
        appLoading()
        const httpFun = httpMap[r.status] || httpMap._
        httpFun(resolve, reject, r, dao, params, config)
      })
      .catch(r => {
        appLoading()
        if (config.silent) {
          $c.warn('请求报错')
        } else if (r.response) {
          const httpFun = httpMap[r.response.status] || httpMap._
          httpFun(resolve, reject, r, dao, params, config)
        } else if (r) {
          $$.err(r)
        } else {
          window.$$.msg.error(msg.emptyErr)
          $$.err(r)
        }
        reject(r)
      })
  })
}
//下载文件
const AxiosDownload = (method, url, params) => {
  const hasToken = getToken()
  return new Promise((resolve, reject) => {
    const req = new XMLHttpRequest()
    req.open(method, url, true)
    req.responseType = 'arraybuffer'
    req.setRequestHeader('x-token', hasToken)
    req.onreadystatechange = () => {
      // readyState == 4说明请求已完成
      if (req.readyState === 4) {
        const data = req.response
        // 获取文件名
        const content = req.getResponseHeader('Content-Disposition')
        const fileName = content && content.split(';')[1].split('filename=')[1]
        if (req.status == 200 || req.status == 304) {
          resolve({ data, fileName })
        } else if (req.status == 401) {
          removeToken()
          localStorage.removeItem('user')
          localStorage.removeItem('power')
          router.replace(`/login`)
        } else {
          reject(data)
        }
      }
    }
    // 发送数据
    req.send(JSON.stringify(params))
  })
}
const $ = {
  get: (url, params, config) => http('GET', url, params, config),
  file: (url, params) =>
    http('POST', url, params, {
      apiPath: '/file',
      isFormData: true
    }),
  post: (url, params, config) => http('POST', url, params, config),
  jsonPost: (url, params, config) => http('POST', url, params, config, true),
  AxiosDownload: (url, params) => AxiosDownload('POST', url, params)
}
export default $
